package com.fourmob.datetimepicker.date;

import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.CommonDialog;
import ohos.app.Context;
import ohos.global.i18n.text.DateFormatUtil;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.miscservices.timeutility.Time;
import ohos.vibrator.agent.VibratorAgent;

import com.fourmob.datetimepicker.ResourceTable;
import com.fourmob.datetimepicker.Utils;
import com.fourmob.datetimepicker.util.DateTimePickerR;
import com.fourmob.datetimepicker.util.RecordDateUtil;

import java.io.IOException;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;

public class DatePickerDialog implements Component.ClickedListener, DatePickerController {

    private static final String KEY_SELECTED_YEAR = "year";
    private static final String KEY_SELECTED_MONTH = "month";
    private static final String KEY_SELECTED_DAY = "day";
    private static final String KEY_VIBRATE = "vibrate";
    private static final int MAX_YEAR = 2028;
    private static final int MIN_YEAR = 1985;

    private static final int UNINITIALIZED = -1;
    private static final int MONTH_AND_DAY_VIEW = 0;
    private static final int YEAR_VIEW = 1;

    public static final int ANIMATION_DELAY = 500;
    public static final String KEY_WEEK_START = "week_start";
    public static final String KEY_YEAR_START = "year_start";
    public static final String KEY_YEAR_END = "year_end";
    public static final String KEY_CURRENT_VIEW = "current_view";
    public static final String KEY_LIST_POSITION = "list_position";
    public static final String KEY_LIST_POSITION_OFFSET = "list_position_offset";

    private static HiLogLabel label = new HiLogLabel(HiLog.LOG_APP, 0x000110, "DatePickerDialogCom");
    private static HiLogLabel label2 = new HiLogLabel(HiLog.LOG_APP, 0x000110, "DatePickerDialogCom1");
    private static HiLogLabel label1 = new HiLogLabel(HiLog.LOG_APP, 0x000110, "DatePickerDialog");

    private static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("dd", Locale.getDefault());
    private static SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy", Locale.getDefault());
    private DateFormatSymbols mDateFormatSymbols = new DateFormatSymbols();

    private final Calendar mCalendar = Calendar.getInstance();
    private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
    private OnDateSetListener mCallBack;

    private AccessibleDateAnimator mAnimator;   // AccessibleDateAnimator 是自定义view
    private boolean mDelayAnimation = true;
    private long mLastVibrate;
    private int mCurrentView = UNINITIALIZED;

    private int mWeekStart = mCalendar.getFirstDayOfWeek();
    private int mMaxYear = MAX_YEAR;
    private int mMinYear = MIN_YEAR;

    private String mSelectDay;
    private String mSelectYear;

    private Text mDayOfWeekView;
    private DayPickerView mDayPickerView;
    private Button mDoneButton;
    private DirectionalLayout mMonthAndDayView;
    private Text mSelectedDayTextView;
    private Text mSelectedMonthTextView;
    private VibratorAgent mVibrator;
    private YearPickerView mYearPickerView;
    private Text mYearView;
    private DirectionalLayout mdate_picker_dialog_layout;
    private DirectionalLayout date_picker_total_direction;

    private boolean mVibrate = true;
    private boolean mCloseOnSingleTapDay;

    private CommonDialog commonDialog;
    private static Context mContext;

    public DatePickerDialog() {
        onStart();
        onActive();
        onCreated();
    }

    private void adjustDayInMonthIfNeeded(int month, int year) {
        HiLog.info(label, "adjstDayInMonthIfNeeded 01 ");
        int day = mCalendar.get(Calendar.DAY_OF_MONTH);
        int daysInMonth = Utils.getDaysInMonth(month, year);
        HiLog.info(label, "adjstDayInMonthIfNeeded 02 " + " day: " + day + " daysInMonth " + daysInMonth);

        if (day > daysInMonth) {
            HiLog.info(label, "adjstDayInMonthIfNeeded 03 ");
            mCalendar.set(Calendar.DAY_OF_MONTH, daysInMonth);
        }
    }

    /**
     * 构造方法
     *
     * @param onDateSetListener 监听器
     * @param context 上下文
     * @param year 年
     * @param month 月
     * @param day 日
     * @param vibrate 是否开启震动
     * @return DatePickerDialog dialog
     */
    public static DatePickerDialog newInstance(OnDateSetListener onDateSetListener,
                                               Context context, int year, int month, int day, boolean vibrate) {
        mContext = context;
        DatePickerDialog datePickerDialog = new DatePickerDialog();
        datePickerDialog.initialize(onDateSetListener, year, month, day, vibrate);
        return datePickerDialog;
    }

    /**
     * 是否震动
     *
     * @param vibrate 是否震动
     ***/
    public void setVibrate(boolean vibrate) {
        mVibrate = vibrate;
    }

    private void setCurrentView(int currentView) {
        setCurrentView(currentView, false);
    }

    private void setCurrentView(int currentView, boolean forceRefresh) {
        switch (currentView) {
            case MONTH_AND_DAY_VIEW:
                HiLog.info(label, "DPD_setCurrentView01");
                HiLog.info(label2, "setCurrentView2 " + forceRefresh);
                AnimatorProperty monthDayAnim = Utils.getPulsePropertyAnimator(mMonthAndDayView, 0.8f, 0.2F);
                if (mDelayAnimation == true) {
                    monthDayAnim.setDelay(ANIMATION_DELAY);
                    monthDayAnim.start();
                    mDelayAnimation = false;
                    HiLog.info(label, "DPD_setCurrentView01");
                }
                RecordDateUtil.setIsFirstChange(true);
                mDayPickerView.onDateChanged();
                HiLog.info(label, "DPD_setCurrentView02");
                if (mCurrentView != currentView || forceRefresh) {
                    mMonthAndDayView.setSelected(true);
                    mYearView.setSelected(false);
                    mAnimator.setDisplayedChild(MONTH_AND_DAY_VIEW);
                    HiLog.info(label, "DPD_setCurrentView03");
                    mCurrentView = currentView;
                }

                monthDayAnim.start();
                HiLog.info(label, "DPD_setCurrentView04");

                choiceColor(1);
                LocalDate date1 = LocalDate.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
                String monthDayDesc = date1.format(formatter);

                mAnimator.setComponentDescription(monthDayDesc);
                Utils.tryAccessibilityAnnounce(mAnimator, mSelectDay);
                HiLog.info(label, "DPD_setCurrentView05:" + mSelectDay);
                break;
            case YEAR_VIEW:
                choiceColor(2);
                HiLog.info(label, "DPD_setCurrentViewYEAR_VIEW");
                AnimatorProperty yearAnim = Utils.getPulsePropertyAnimator(mYearView, 1.0f, 0.2f);
                if (mDelayAnimation) {
                    yearAnim.setDelay(ANIMATION_DELAY);
                    mDelayAnimation = false;
                }
                HiLog.info(label, "DPD_setCurrentViewYEAR_VIEW01");
                mYearPickerView.onDateChanged();
                if (mCurrentView != currentView || forceRefresh) {
                    HiLog.info(label, "DPD_setCurrentViewYEAR_VIEW02");
                    mMonthAndDayView.setSelected(false);
                    mYearView.setSelected(true);
                    mAnimator.setDisplayedChild(YEAR_VIEW);
                    mCurrentView = currentView;
                    HiLog.info(label, "DPD_setCurrentViewYEAR_VIEW03");
                }
                HiLog.info(label, "DPD_setCurrentViewYEAR_VIEW04");
                yearAnim.start();
                Utils.tryAccessibilityAnnounce(mAnimator, mSelectYear);
                HiLog.info(label, "DPD_setCurrentViewYEAR_VIEW05");
                break;
        }
    }

    protected static float scaleHs(float v) {
        float res = 0;
        if (v <= (float) 1 / 3)
            res = (float) (-1.2 * v + 1);
        else if (v > (float) 1 / 3 && v <= (float) 2 / 3)
            res = (float) (-0.3 * v + 0.7);
        else if (v > (float) 2 / 3)
            res = (float) (1.5 * v - 0.5);
        return res;
    }

    private void updateDisplay(boolean announce) {
        if (mDayOfWeekView != null) {
            mDayOfWeekView.setText(mCalendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG,
                Locale.getDefault()).toUpperCase(Locale.getDefault()));
        }

        if (this.mDayOfWeekView != null) {
            this.mCalendar.setFirstDayOfWeek(mWeekStart);
            this.mDayOfWeekView.setText(mDateFormatSymbols.getWeekdays()
                [this.mCalendar.get(Calendar.DAY_OF_WEEK)].toUpperCase(Locale.getDefault()));
        }
        this.mSelectedMonthTextView.setText(mDateFormatSymbols.getMonths()
            [this.mCalendar.get(Calendar.MONTH)].toUpperCase(Locale.US));
        mSelectedDayTextView.setText(DAY_FORMAT.format(mCalendar.getTime()));

        mYearView.setText(YEAR_FORMAT.format(mCalendar.getTime()));
        RecordDateUtil.setDay(Integer.parseInt(DAY_FORMAT.format(mCalendar.getTime())));
        RecordDateUtil.setMonth(this.mCalendar.get((Calendar.MONTH)));
        RecordDateUtil.setYear(Integer.parseInt(YEAR_FORMAT.format(mCalendar.getTime())));
        long millis = mCalendar.getTimeInMillis();
    /*    mAnimator.setDateMillis(millis);*/

        int flags = DateFormat.YEAR_FIELD | DateFormat.DATE_FIELD;
        LocalDate localDate = LocalDate.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy MM dd");
        String monthAndDayText = localDate.format(dateTimeFormatter);
        mMonthAndDayView.setAccessibilityDescription(monthAndDayText);
        if (announce) {
            DateFormatUtil.format("", "", "", millis, millis);
            Utils.tryAccessibilityAnnounce(mAnimator, "");
        }
    }

    private void updatePickers() {
        Iterator<OnDateChangedListener> iterator = mListeners.iterator();
        while (iterator.hasNext()) {
            iterator.next().onDateChanged();
        }
    }

    private void choiceColor(int colorChoice) {
        switch (colorChoice) {
            case 1:
                mSelectedDayTextView.setTextColor(new Color(Color.getIntColor("#32b5e5")));
                mSelectedMonthTextView.setTextColor(new Color(Color.getIntColor("#32b5e5")));
                mYearView.setTextColor(new Color(Color.getIntColor("#999999")));
                break;
            case 2:
                mSelectedDayTextView.setTextColor(new Color(Color.getIntColor("#999999")));
                mSelectedMonthTextView.setTextColor(new Color(Color.getIntColor("#999999")));
                mYearView.setTextColor(new Color(Color.getIntColor("#32b5e5")));
                break;
            default:
                break;
        }
    }

    public int getFirstDayOfWeek() {
        return mWeekStart;
    }

    public int getMaxYear() {
        return mMaxYear;
    }

    public int getMinYear() {
        return mMinYear;
    }

    public SimpleMonthAdapter.CalendarDay getSelectedDay() {
        return new SimpleMonthAdapter.CalendarDay(mCalendar);
    }

    @Override
    public void onDayOfMonthSelected(int year, int month, int day) {
        HiLog.info(label, "onDayofMonthSelected: " + year +
            ", month: " + month + " day: " + day);

        mCalendar.set(Calendar.YEAR, year);
        mCalendar.set(Calendar.MONTH, month);
        mCalendar.set(Calendar.DAY_OF_MONTH, day);
        RecordDateUtil.setMonth(month);
        RecordDateUtil.setYear(year);
        RecordDateUtil.setDay(day);
        dateTimePickerRS.putInt(mContext, KEY_SELECTED_YEAR, year);
        dateTimePickerRS.putInt(mContext, KEY_SELECTED_MONTH, month);
        dateTimePickerRS.putInt(mContext, KEY_SELECTED_DAY, day);

        updatePickers();
        updateDisplay(true);

        if (mCloseOnSingleTapDay && RecordDateUtil.isHasScroll() == false) {
            onDoneButtonClick();
        }
    }

    public void initialize(OnDateSetListener onDateSetListener, int year, int month, int day, boolean vibrate) {
        if (year > MAX_YEAR)
            throw new IllegalArgumentException("year end must < " + MAX_YEAR);
        if (year < MIN_YEAR)
            throw new IllegalArgumentException("year end must > " + MIN_YEAR);
        mCallBack = onDateSetListener;
        mCalendar.set(Calendar.YEAR, year);
        mCalendar.set(Calendar.MONTH, month);
        mCalendar.set(Calendar.DAY_OF_MONTH, day);
        mVibrate = vibrate;
    }

    /**
     * 日历选择器和年份选择器
     *
     * @param view
     **/
    public void onClick(Component view) {
        tryVibrate();
        if (view.getId() == ResourceTable.Id_date_picker_year)
            setCurrentView(YEAR_VIEW);
        else if (view.getId() == ResourceTable.Id_date_picker_month_and_day)
            setCurrentView(MONTH_AND_DAY_VIEW);
    }

    protected void onCreated() {
        HiLog.info(label, "life onComponent");
        Component component = LayoutScatter.getInstance(mContext).
            parse(ResourceTable.Layout_date_picker_dialog, null, false);
        mdate_picker_dialog_layout = (DirectionalLayout) component.findComponentById(
            ResourceTable.Id_date_picker_dialog_layout);
        date_picker_total_direction = (DirectionalLayout) component.findComponentById(
            ResourceTable.Id_date_picker_total_direction);
        mDayOfWeekView = ((Text) component.findComponentById(ResourceTable.Id_date_picker_header));
        mMonthAndDayView = ((DirectionalLayout) component.findComponentById(
            ResourceTable.Id_date_picker_month_and_day));

        mSelectedMonthTextView = ((Text) component.findComponentById(ResourceTable.Id_date_picker_month));
        mSelectedDayTextView = ((Text) component.findComponentById(ResourceTable.Id_date_picker_day));
        mYearView = ((Text) component.findComponentById(ResourceTable.Id_date_picker_year));

        int listPosition = -1;
        int currentView = MONTH_AND_DAY_VIEW;
        int listPositionOffset = 0;
        HiLog.info(label, "setCurrentView " + (params != null));
        if (params != null) {
            mWeekStart = (int) params.getParam(KEY_WEEK_START);
            mMinYear = (int) params.getParam(KEY_YEAR_START);
            mMaxYear = (int) params.getParam(KEY_YEAR_END);
            currentView = (int) params.getParam(KEY_CURRENT_VIEW);
            listPosition = (int) params.getParam(KEY_LIST_POSITION);
        }
        Context fractionAbility = mContext;
        HiLog.info(label, "mMinYear: " + mMinYear + ", mMaxYear: " + mMaxYear);
        HiLog.info(label, "oncreate " + mCalendar.get(Calendar.YEAR) + ", " +
            "" + mCalendar.get(Calendar.MONTH) + ", " + mCalendar.get(Calendar.DAY_OF_MONTH));
        mDayPickerView = new DayPickerView(fractionAbility, this);
        mYearPickerView = new YearPickerView(fractionAbility, this);
        ResourceManager resourceManager = fractionAbility.getResourceManager();

        try {
            mSelectDay = resourceManager.getElement(ResourceTable.String_select_day).getString();
            mSelectYear = resourceManager.getElement(ResourceTable.String_select_year).getString();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
           mAnimator = (AccessibleDateAnimator) component.findComponentById(ResourceTable.Id_animator);
            mAnimator.addComponent(mDayPickerView);
            mAnimator.addComponent(mYearPickerView);
            mAnimator.createAnimatorProperty().alphaFrom(0).alpha(1).setDelay(300).start();
            mAnimator.createAnimatorProperty().alphaFrom(1).alpha(0).setDelay(300).start();

            mDoneButton = ((Button) component.findComponentById(ResourceTable.Id_done));
            mDoneButton.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    mDoneButton.setText("Done Finish");
                    onDoneButtonClick();
                }
            });

            mdate_picker_dialog_layout.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    dismiss();
                }
            });
            date_picker_total_direction.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {

                }
            });
            commonDialog = new CommonDialog(mContext);
            commonDialog.setAutoClosable(true);
            commonDialog.setContentCustomComponent(component);
            commonDialog.setTransparent(true);
            mMonthAndDayView.setClickedListener(this);
            mYearView.setClickedListener(this);
            mYearPickerView.setVisibility(Component.INVISIBLE);
            updateDisplay(false);
            choiceColor(1);
            HiLog.info(label2, "setCurrentView1 " + currentView);
            setCurrentView(currentView, true);

            if (listPosition != -1) {
                if (currentView == MONTH_AND_DAY_VIEW) {
                    HiLog.info(label, ": " + listPosition);

                    mDayPickerView.postSetSelection(listPosition);
                }
                if (currentView == YEAR_VIEW) {
                    mYearPickerView.postSetSelectionFromTop(listPosition, listPositionOffset);
                }
            }
            HiLog.info(label2, "setCurrentView " + mDelayAnimation);


    }

    private void onDoneButtonClick() {
        tryVibrate();
        if (mCallBack != null) {
            mCallBack.onDateSet(this, mCalendar.get(Calendar.YEAR),
                mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
        }
        dismiss();  // 原来是DialogFragment,  原来是dismiss,  在目前状态下改为了Fraction
    }

    private IntentParams params = null;
    private DateTimePickerR dateTimePickerRS;

    protected void onStart() {
        HiLog.info(label, "life onStart");
        mVibrator = new VibratorAgent();
        dateTimePickerRS = DateTimePickerR.getInstance();
        int year = dateTimePickerRS.getInt(mContext, KEY_SELECTED_YEAR, 1981);
        int month = dateTimePickerRS.getInt(mContext, KEY_SELECTED_MONTH, 32);
        int selectday = dateTimePickerRS.getInt(mContext, KEY_SELECTED_DAY, 32);
        HiLog.info(label, "onStart " + year + " month: " + month + " day " + selectday);
        params = new IntentParams();
        if (year != 1981 && month != 32 && selectday != 32) {
            params.setParam(KEY_SELECTED_YEAR, year);
            params.setParam(KEY_SELECTED_MONTH, month);
            params.setParam(KEY_SELECTED_DAY, selectday);
        } else {
            params.setParam(KEY_SELECTED_YEAR, mCalendar.get(Calendar.YEAR));
            params.setParam(KEY_SELECTED_MONTH, mCalendar.get(Calendar.MONTH));
            params.setParam(KEY_SELECTED_DAY, mCalendar.get(Calendar.DAY_OF_MONTH));

            HiLog.info(label, "life DatePicker " + params.getParam(KEY_SELECTED_YEAR) + ", month: "
                + params.getParam(KEY_SELECTED_MONTH) + ", day: " + params.getParam(KEY_SELECTED_DAY));
            Intent intent1 = new Intent();
        }

        params.setParam(KEY_WEEK_START, mWeekStart);
        params.setParam(KEY_YEAR_START, mMinYear);
        params.setParam(KEY_YEAR_END, mMaxYear);
        params.setParam(KEY_CURRENT_VIEW, mCurrentView);
        int listPosition = -1;
        if (mCurrentView == 0) {
            listPosition = mDayPickerView.getMostVisiblePosition();
        }

        if (mCurrentView == 1) {
            listPosition = mYearPickerView.getFirstVisibleItemPosition();
            params.setParam(KEY_LIST_POSITION_OFFSET, listPosition);
        }
        params.setParam(KEY_LIST_POSITION, listPosition);
        params.setParam(KEY_VIBRATE, mVibrate);

    }

    protected void onActive() {
        HiLog.info(label, "life onActive");
        if (params != null) {
            HiLog.info(label, "life onActive " + params.getParam(KEY_SELECTED_YEAR) + ", month: "
                + params.getParam(KEY_SELECTED_MONTH) + ", day: " + params.getParam(KEY_SELECTED_DAY));

            mCalendar.set(Calendar.YEAR, (int) params.getParam(KEY_SELECTED_YEAR));
            mCalendar.set(Calendar.MONTH, (int) params.getParam(KEY_SELECTED_MONTH));
            mCalendar.set(Calendar.DAY_OF_MONTH, (int) params.getParam(KEY_SELECTED_DAY));
            mVibrate = (Boolean) params.getParam(KEY_VIBRATE);
        }
    }

    /**
     * 打开dialog
     */
    public void show() {
        if (commonDialog != null && commonDialog.isShowing() == false) {
            RecordDateUtil.setIsFirstChange(true);
            commonDialog.show();
            setCurrentView(0, true);
        }
    }

    /**
     * 关闭dialog
     */
    public void dismiss() {
        if (commonDialog != null) {
            RecordDateUtil.setIsFirstChange(false);
            commonDialog.destroy();
        }
    }

    /***
     * 选择年份
     * @param year
     *
     ****/
    public void onYearSelected(int year) {
        HiLog.info(label, "onYearSelected.. " + year + " " + mCalendar.get(Calendar.MONTH) + " " +
            mCalendar.get(Calendar.DAY_OF_MONTH));
        int month = mCalendar.get(Calendar.MONTH);
        int day = mCalendar.get(Calendar.DAY_OF_MONTH);
        dateTimePickerRS.putInt(mContext, KEY_SELECTED_YEAR, year);
        dateTimePickerRS.putInt(mContext, KEY_SELECTED_MONTH, month);
        dateTimePickerRS.putInt(mContext, KEY_SELECTED_DAY, day);
        RecordDateUtil.setMonth(month);
        RecordDateUtil.setYear(year);
        RecordDateUtil.setDay(day);

        adjustDayInMonthIfNeeded(mCalendar.get(Calendar.MONTH), year);
        mCalendar.set(Calendar.YEAR, year);
        HiLog.info(label, "adjstDayInMonthIfNeeded 02a " + mCalendar.get(Calendar.YEAR) + "," +
            " " + mCalendar.get(Calendar.MONTH) + ", " + mCalendar.get(Calendar.DAY_OF_MONTH));
        updatePickers();
        setCurrentView(MONTH_AND_DAY_VIEW);
        updateDisplay(true);
    }

    public void registerOnDateChangedListener(OnDateChangedListener onDateChangedListener) {
        mListeners.add(onDateChangedListener);
    }

    @Override
    public void tryVibrate() {
        if (mVibrator != null && mVibrate) {
            long timeInMills = Time.getCurrentTime();
            if (timeInMills - mLastVibrate >= 125L) {
                mVibrator.startOnce(5);
                mLastVibrate = timeInMills;
            }
        }
    }

    /***
     * 设置每周的第一天
     * @param startOfWeek
     **/
    public void setFirstDayOfWeek(int startOfWeek) {
        if (startOfWeek < Calendar.SUNDAY || startOfWeek > Calendar.SATURDAY) {
            throw new IllegalArgumentException("Value must be between Calendar.SUNDAY and "
                + "Calendar.SATURDAY");
        }
        mWeekStart = startOfWeek;
        if (mDayPickerView != null) {
            mDayPickerView.onChange();
        }
    }

    /**
     * 设置日期监听器
     *
     * @param onDateSetListener 监听器
     */
    public void setOnDateSetListener(OnDateSetListener onDateSetListener) {
        mCallBack = onDateSetListener;
    }

    /**
     * 设置最大最小年份
     *
     * @param minYear 最小年份
     * @param maxYear 最大年份
     */
    public void setYearRange(int minYear, int maxYear) {
        HiLog.info(label, "setYearRange   minYear: " + minYear + ", maxYear: " + maxYear);
        if (maxYear < minYear)
            throw new IllegalArgumentException("Year end must be larger than year start");
        if (maxYear > MAX_YEAR)
            throw new IllegalArgumentException("max year end must < " + MAX_YEAR);
        if (minYear < MIN_YEAR)
            throw new IllegalArgumentException("min year end must > " + MIN_YEAR);
        mMinYear = minYear;
        mMaxYear = maxYear;
        HiLog.info(label, "setYearRange0   minYear: " + minYear + ", maxYear: " + maxYear);

        if (mDayPickerView != null) {
            HiLog.info(label, "setYearRange1   minYear: " + minYear + ", maxYear: " + maxYear);
            mDayPickerView.onChange();
        }
    }

    /**
     * 设置是否单击日期时关闭dialog
     *
     * @param closeOnSingleTapDay 是否关闭
     */
    public void setCloseOnSingleTapDay(boolean closeOnSingleTapDay) {
        mCloseOnSingleTapDay = closeOnSingleTapDay;
        RecordDateUtil.setCloseDay(mCloseOnSingleTapDay);
    }

    static abstract interface OnDateChangedListener {
        public abstract void onDateChanged();
    }

    public static abstract interface OnDateSetListener {
        public abstract void onDateSet(DatePickerDialog datePickerDialog, int year, int month, int day);
    }
}